<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>花艺AI测试应用</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
    <style>
        body { padding-top: 2rem; }
        .header { margin-bottom: 2rem; }
        .form-container { max-width: 800px; margin: 0 auto; }
        .recording { color: red; }
        #recording-status { font-weight: bold; }
        .voice-controls { display: flex; gap: 10px; align-items: center; margin-bottom: 15px; }
        .audio-player { margin-top: 15px; width: 100%; }
        /* 添加预设文本按钮样式 */
        .preset-questions { margin-top: 15px; }
        .preset-btn { margin-bottom: 8px; text-align: left; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header text-center">
            <h1>花艺AI测试应用</h1>
            <p class="lead">使用RAG系统和DeepSeek API进行花艺知识查询和设计</p>
            <nav class="nav justify-content-center">
                <a class="nav-link" href="/">首页</a>
                <a class="nav-link" href="/upload">上传知识</a>
                <a class="nav-link" href="/image">生成图像</a>
                <a class="nav-link" href="/speech">语音交互</a>
                <a class="nav-link" href="/video/list">视频库</a>
                <a class="nav-link" href="/status">系统状态</a>
            </nav>
        </div>

        <div class="form-container">
            <div class="card">
                <div class="card-header bg-primary text-white">
                    <h5 class="mb-0">花艺知识查询</h5>
                </div>
                <div class="card-body">
                    <!-- 添加语音输入控件 -->
                    <div class="voice-controls">
                        <button id="start-recording" class="btn btn-outline-primary btn-sm"><i class="bi bi-mic"></i> 语音输入</button>
                        <button id="stop-recording" class="btn btn-outline-danger btn-sm" disabled><i class="bi bi-stop-fill"></i> 停止录音</button>
                        <span id="recording-status"></span>
                    </div>

                    <form action="/query" method="post" id="query-form">
                        <div class="mb-3">
                            <label for="query" class="form-label">输入你的花艺问题:</label>
                            <textarea class="form-control" id="query" name="query" rows="3" required></textarea>
                        </div>

                        <!-- 添加预设问题按钮 -->
                        <div class="preset-questions mb-3">
                            <label class="form-label">或选择预设问题:</label>
                            <div class="d-grid gap-2">
                                <button type="button" class="btn btn-outline-secondary preset-btn" data-question="推荐适合中式插花的花材"><i class="bi bi-flower1"></i> 推荐适合中式插花的花材</button>
                                <button type="button" class="btn btn-outline-secondary preset-btn" data-question="欧式插花与日式插花的区别"><i class="bi bi-flower2"></i> 欧式插花与日式插花的区别</button>
                                <button type="button" class="btn btn-outline-secondary preset-btn" data-question="如何搭配红色和白色的花"><i class="bi bi-palette"></i> 如何搭配红色和白色的花</button>
                            </div>
                        </div>

                        <div class="mb-3 form-check">
                            <input type="checkbox" class="form-check-input" id="generate_image" name="generate_image">
                            <label class="form-check-label" for="generate_image">生成相关图像</label>
                        </div>
                        <div class="mb-3 form-check">
                            <input type="checkbox" class="form-check-input" id="voice_response" name="voice_response">
                            <label class="form-check-label" for="voice_response">语音回答 <span class="badge bg-warning text-dark">可能暂时不可用</span></label>
                        </div>
                        <button type="submit" class="btn btn-primary">提交问题</button>
                    </form>
                </div>
                <div class="card-footer text-muted">
                    提示: 点击上方预设问题按钮可快速选择常见问题
                </div>
            </div>

            <!-- 显示回答的结果区域 -->
            <div class="card mt-4 d-none" id="result-card">
                <div class="card-header bg-success text-white">
                    <h5 class="mb-0">回答</h5>
                </div>
                <div class="card-body">
                    <div id="response-text"></div>

                    <!-- 添加语音播放控件 -->
                    <div id="audio-container" class="mt-3 d-none">
                        <h6>语音回答:</h6>
                        <audio controls id="response-audio" class="audio-player"></audio>
                    </div>

                    <!-- 图像容器 -->
                    <div id="image-container" class="mt-3 d-none">
                        <h6>生成的图像:</h6>
                        <img id="response-image" class="img-fluid" src="" alt="生成的花艺图像">
                    </div>
                </div>
            </div>

            <!-- 快速访问区块 -->
            <div class="card mt-4">
                <div class="card-header bg-info text-white">
                    <h5 class="mb-0">快速访问</h5>
                </div>
                <div class="card-body">
                    <div class="row">
                        <div class="col-md-6 mb-3">
                            <div class="d-grid">
                                <a href="/image" class="btn btn-outline-primary">生成花艺图像</a>
                            </div>
                        </div>
                        <div class="col-md-6 mb-3">
                            <div class="d-grid">
                                <a href="/speech" class="btn btn-outline-success">语音交互</a>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>

    <script>
        // 语音交互功能
        document.addEventListener('DOMContentLoaded', function() {
            // 录音相关变量
            let mediaRecorder;
            let audioChunks = [];
            let recording = false;
            let speechToTextUnavailable = false; // 标记语音识别功能是否不可用

            // 页面元素
            const startButton = document.getElementById('start-recording');
            const stopButton = document.getElementById('stop-recording');
            const recordingStatus = document.getElementById('recording-status');
            const queryTextarea = document.getElementById('query');
            const generateImageCheckbox = document.getElementById('generate_image');
            const voiceResponseCheckbox = document.getElementById('voice_response');
            const queryForm = document.getElementById('query-form');
            const resultCard = document.getElementById('result-card');
            const responseText = document.getElementById('response-text');
            const audioContainer = document.getElementById('audio-container');
            const responseAudio = document.getElementById('response-audio');
            const imageContainer = document.getElementById('image-container');
            const responseImage = document.getElementById('response-image');
            const presetButtons = document.querySelectorAll('.preset-btn');

            // 预设问题按钮点击事件
            presetButtons.forEach(button => {
                button.addEventListener('click', function() {
                    const question = this.getAttribute('data-question');
                    queryTextarea.value = question;
                    queryTextarea.focus();
                });
            });

            // 开始录音
            startButton.addEventListener('click', async () => {
                // 如果语音识别已知不可用，显示提示并返回
                if (speechToTextUnavailable) {
                    recordingStatus.innerHTML = `<span class="text-danger">语音识别功能暂时不可用，请使用键盘输入或选择预设问题</span>`;
                    setTimeout(() => {
                        recordingStatus.textContent = '';
                    }, 3000);
                    return;
                }

                try {
                    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
                    mediaRecorder = new MediaRecorder(stream);
                    audioChunks = [];

                    mediaRecorder.addEventListener('dataavailable', event => {
                        audioChunks.push(event.data);
                    });

                    mediaRecorder.addEventListener('stop', () => {
                        recording = false;
                        startButton.disabled = false;
                        stopButton.disabled = true;

                        // 处理录制的音频
                        processAudio();
                    });

                    mediaRecorder.start();
                    recording = true;
                    recordingStatus.textContent = '正在录音...';
                    recordingStatus.className = 'recording';
                    startButton.disabled = true;
                    stopButton.disabled = false;
                } catch (err) {
                    console.error('录音初始化失败:', err);
                    recordingStatus.innerHTML = `<span class="text-danger">无法访问麦克风，请确保已授权浏览器使用麦克风</span>`;
                    setTimeout(() => {
                        recordingStatus.textContent = '';
                    }, 3000);
                }
            });

            // 停止录音
            stopButton.addEventListener('click', () => {
                if (mediaRecorder && recording) {
                    mediaRecorder.stop();
                }
            });

            // 处理录音数据，发送到服务器进行语音识别
            async function processAudio() {
                const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
                const formData = new FormData();
                formData.append('audio', audioBlob);
                formData.append('dialect', 'mandarin'); // 默认使用普通话

                try {
                    recordingStatus.textContent = '正在识别...';
                    recordingStatus.className = 'text-warning';

                    // 使用正确的API端点
                    const response = await fetch('/speech-to-text', {
                        method: 'POST',
                        body: formData
                    });

                    console.log('API返回状态:', response.status);

                    if (response.ok) {
                        try {
                            const result = await response.json();
                            console.log('API返回结果:', result);

                            // 检查是否存在错误或警告信息
                            if (result.error) {
                                console.error('API返回错误:', result.error);

                                // 检查是否是后端DeepSeekASR错误
                                if (result.error.includes('DeepSeekASR') ||
                                    result.error.includes('is_available') ||
                                    result.error.includes('语音识别失败')) {

                                    // 标记语音识别功能不可用
                                    speechToTextUnavailable = true;

                                    // 修改UI以反映语音识别不可用
                                    startButton.classList.add('disabled');
                                    startButton.title = '语音识别功能暂时不可用';

                                    recordingStatus.innerHTML = `<span class="text-danger">语音识别功能暂时不可用，请使用键盘输入或选择预设问题</span>`;
                                    setTimeout(() => {
                                        recordingStatus.textContent = '';
                                    }, 5000);
                                } else {
                                    recordingStatus.textContent = `错误: ${result.error}`;
                                    recordingStatus.className = 'text-danger';
                                    setTimeout(() => {
                                        recordingStatus.textContent = '';
                                    }, 3000);
                                }
                                return;
                            }

                            // 获取转写文本
                            const transcription = result.transcription || '';

                            // 检查是否有意义的文本
                            if (transcription === '[语音识别失败]' || transcription === '') {
                                recordingStatus.innerHTML = `<span class="text-danger">无法识别语音，请尝试说得更清晰或使用预设问题</span>`;
                                recordingStatus.className = 'text-danger';
                                setTimeout(() => {
                                    recordingStatus.textContent = '';
                                }, 3000);
                                return;
                            }

                            console.log('识别到的文本:', transcription);

                            // 设置文本框的值
                            queryTextarea.value = transcription;

                            // 显示成功消息
                            recordingStatus.innerHTML = `<span class="text-success fw-bold">识别成功!</span>`;
                            recordingStatus.className = 'text-success';

                            // 高亮显示文本区域
                            queryTextarea.classList.add('border-success');
                            queryTextarea.classList.add('bg-light');
                            queryTextarea.focus();

                            // 添加提示信息
                            const successMessage = document.createElement('div');
                            successMessage.id = 'speech-success-message';
                            successMessage.className = 'alert alert-success mt-2';
                            successMessage.innerHTML = `
                                <i class="bi bi-check-circle-fill"></i> 语音已转为文字: <strong>${transcription}</strong>
                                <p class="mb-0 mt-1">请检查内容并点击"提交问题"继续</p>
                            `;

                            // 防止重复添加消息
                            const existingMessage = document.getElementById('speech-success-message');
                            if (existingMessage) {
                                existingMessage.remove();
                            }

                            queryTextarea.parentNode.appendChild(successMessage);

                            // 8秒后恢复状态
                            setTimeout(() => {
                                recordingStatus.textContent = '';
                                recordingStatus.className = '';
                                queryTextarea.classList.remove('border-success');
                                queryTextarea.classList.remove('bg-light');
                                if (document.getElementById('speech-success-message')) {
                                    document.getElementById('speech-success-message').remove();
                                }
                            }, 8000);
                        } catch (jsonError) {
                            console.error('解析API响应失败:', jsonError);
                            recordingStatus.innerHTML = `<span class="text-danger">处理响应失败，请用键盘输入</span>`;
                            recordingStatus.className = 'text-danger';

                            // 3秒后清除错误信息
                            setTimeout(() => {
                                recordingStatus.textContent = '';
                            }, 3000);
                        }
                    } else {
                        console.error('API请求失败:', response.status, response.statusText);

                        // 处理404等特定错误
                        if (response.status === 404) {
                            // 标记语音识别不可用
                            speechToTextUnavailable = true;
                            startButton.classList.add('disabled');
                            startButton.title = '语音识别功能暂时不可用';

                            recordingStatus.innerHTML = `<span class="text-danger">语音识别服务不可用，请使用键盘输入</span>`;
                        } else {
                            try {
                                const errorData = await response.json();
                                console.error('API错误详情:', errorData);
                                recordingStatus.textContent = `错误: ${errorData.error || errorData.detail || '识别失败'} (${response.status})`;
                            } catch (e) {
                                recordingStatus.textContent = `错误: 识别失败 (${response.status})`;
                            }
                        }

                        recordingStatus.className = 'text-danger';

                        // 3秒后清除错误信息
                        setTimeout(() => {
                            recordingStatus.textContent = '';
                        }, 3000);
                    }
                } catch (err) {
                    console.error('处理音频时出错:', err);
                    recordingStatus.textContent = `错误: ${err.message || '无法处理录音'}`;
                    recordingStatus.className = 'text-danger';

                    // 3秒后清除错误信息
                    setTimeout(() => {
                        recordingStatus.textContent = '';
                    }, 3000);
                }
            }

            // 处理表单提交
            queryForm.addEventListener('submit', async function(e) {
                e.preventDefault();

                const query = queryTextarea.value.trim();
                if (!query) return;

                const generateImage = generateImageCheckbox.checked;
                const voiceResponse = voiceResponseCheckbox.checked;

                // 显示加载状态
                responseText.innerHTML = '<div class="text-center"><div class="spinner-border text-primary" role="status"></div><p>正在处理您的问题...</p></div>';
                resultCard.classList.remove('d-none');
                audioContainer.classList.add('d-none');
                imageContainer.classList.add('d-none');

                try {
                    // 发送查询请求
                    const response = await fetch('/query', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify({
                            query: query,
                            generate_image: generateImage
                        })
                    });

                    // 检查内容类型
                    const contentType = response.headers.get('Content-Type');

                    if (response.ok) {
                        try {
                            // 只有当内容类型是JSON时才尝试解析JSON
                            if (contentType && contentType.includes('application/json')) {
                                const result = await response.json();

                                // 显示文本回答
                                responseText.innerHTML = result.response;

                                // 如果生成了图像，显示图像
                                if (result.image_url) {
                                    responseImage.src = result.image_url;
                                    imageContainer.classList.remove('d-none');
                                } else {
                                    imageContainer.classList.add('d-none');
                                }

                                // 如果需要语音回答，生成语音
                                if (voiceResponse) {
                                    try {
                                        // 显示加载状态
                                        audioContainer.classList.remove('d-none');
                                        responseAudio.innerHTML = '<p>正在生成语音...</p>';

                                        // 发送文字转语音请求
                                        const ttsResponse = await fetch('/text-to-speech', {
                                            method: 'POST',
                                            headers: {
                                                'Content-Type': 'application/json'
                                            },
                                            body: JSON.stringify({
                                                text: result.response,
                                                dialect: 'mandarin'
                                            })
                                        });

                                        // 检查TTS响应的内容类型
                                        const ttsContentType = ttsResponse.headers.get('Content-Type');

                                        if (ttsResponse.ok) {
                                            try {
                                                if (ttsContentType && ttsContentType.includes('application/json')) {
                                                    const ttsResult = await ttsResponse.json();

                                                    if (ttsResult.audio_base64) {
                                                        // 设置音频源并播放
                                                        responseAudio.src = `data:audio/wav;base64,${ttsResult.audio_base64}`;
                                                        audioContainer.classList.remove('d-none');

                                                        // 自动播放语音
                                                        responseAudio.play();
                                                    } else {
                                                        // 没有音频数据
                                                        console.warn('TTS响应中没有音频数据');
                                                        audioContainer.classList.add('d-none');

                                                        // 显示警告但不影响主UI
                                                        const ttsAlert = document.createElement('div');
                                                        ttsAlert.className = 'alert alert-warning mt-2';
                                                        ttsAlert.textContent = '语音生成失败: 未收到音频数据';
                                                        responseText.appendChild(ttsAlert);

                                                        // 禁用语音选项
                                                        voiceResponseCheckbox.checked = false;

                                                        // 5秒后移除警告
                                                        setTimeout(() => {
                                                            if (ttsAlert.parentNode) {
                                                                ttsAlert.parentNode.removeChild(ttsAlert);
                                                            }
                                                        }, 5000);
                                                    }
                                                } else {
                                                    throw new Error('响应不是JSON格式');
                                                }
                                            } catch (jsonError) {
                                                console.error('解析TTS响应失败:', jsonError);

                                                try {
                                                    // 尝试获取原始文本查看问题
                                                    const rawText = await ttsResponse.text();
                                                    console.log('TTS原始响应:', rawText.substring(0, 200));
                                                } catch (e) {
                                                    console.error('无法读取TTS响应文本');
                                                }

                                                audioContainer.classList.add('d-none');

                                                // 显示警告
                                                const ttsAlert = document.createElement('div');
                                                ttsAlert.className = 'alert alert-warning mt-2';
                                                ttsAlert.textContent = '语音生成失败: 响应格式错误';
                                                responseText.appendChild(ttsAlert);

                                                // 禁用语音选项
                                                voiceResponseCheckbox.checked = false;

                                                // 5秒后移除警告
                                                setTimeout(() => {
                                                    if (ttsAlert.parentNode) {
                                                        ttsAlert.parentNode.removeChild(ttsAlert);
                                                    }
                                                }, 5000);
                                            }
                                        } else {
                                            console.error('TTS请求失败:', ttsResponse.status);

                                            try {
                                                const errorText = await ttsResponse.text();
                                                console.error('TTS错误详情:', errorText.substring(0, 200));
                                            } catch (e) {
                                                console.error('无法读取TTS错误内容');
                                            }

                                            audioContainer.classList.add('d-none');

                                            // 禁用语音选项
                                            voiceResponseCheckbox.checked = false;

                                            // 显示警告但不影响主UI
                                            const ttsAlert = document.createElement('div');
                                            ttsAlert.className = 'alert alert-warning mt-2';
                                            ttsAlert.textContent = '语音功能暂时不可用';
                                            responseText.appendChild(ttsAlert);

                                            // 5秒后移除警告
                                            setTimeout(() => {
                                                if (ttsAlert.parentNode) {
                                                    ttsAlert.parentNode.removeChild(ttsAlert);
                                                }
                                            }, 5000);
                                        }
                                    } catch (ttsError) {
                                        console.error('TTS请求错误:', ttsError);
                                        audioContainer.classList.add('d-none');

                                        // 禁用语音选项
                                        voiceResponseCheckbox.checked = false;

                                        // 显示警告但不影响主UI
                                        const ttsAlert = document.createElement('div');
                                        ttsAlert.className = 'alert alert-warning mt-2';
                                        ttsAlert.textContent = `语音生成失败: ${ttsError.message || '网络错误'}`;
                                        responseText.appendChild(ttsAlert);

                                        // 5秒后移除警告
                                        setTimeout(() => {
                                            if (ttsAlert.parentNode) {
                                                ttsAlert.parentNode.removeChild(ttsAlert);
                                            }
                                        }, 5000);
                                    }
                                } else {
                                    audioContainer.classList.add('d-none');
                                }
                            } else {
                                // 服务器返回的不是JSON
                                console.error('服务器返回了非JSON内容:', contentType);
                                try {
                                    const textContent = await response.text();
                                    console.error('响应内容:', textContent.substring(0, 200));
                                    responseText.innerHTML = `<div class="alert alert-danger">查询失败: 服务器返回非JSON格式的响应</div>`;
                                } catch (e) {
                                    responseText.innerHTML = `<div class="alert alert-danger">查询失败: 服务器返回意外的响应格式</div>`;
                                }
                                audioContainer.classList.add('d-none');
                                imageContainer.classList.add('d-none');
                            }
                        } catch (parseError) {
                            console.error('解析响应失败:', parseError);

                            try {
                                const rawText = await response.text();
                                console.log('原始响应:', rawText.substring(0, 200));

                                if (rawText.indexOf('<!DOCTYPE html>') >= 0 || rawText.indexOf('<html') >= 0) {
                                    responseText.innerHTML = `<div class="alert alert-danger">查询失败: 服务器返回了HTML页面而不是JSON数据</div>`;
                                } else {
                                    responseText.innerHTML = `<div class="alert alert-danger">查询失败: 无法解析服务器响应</div>`;
                                }
                            } catch (e) {
                                responseText.innerHTML = `<div class="alert alert-danger">查询失败: ${parseError.message || '响应格式错误'}</div>`;
                            }

                            audioContainer.classList.add('d-none');
                            imageContainer.classList.add('d-none');
                        }
                    } else {
                        // 处理错误状态码
                        console.error('查询请求失败:', response.status);
                        try {
                            // 尝试解析错误消息
                            if (contentType && contentType.includes('application/json')) {
                                const errorData = await response.json();
                                responseText.innerHTML = `<div class="alert alert-danger">查询失败: ${errorData.error || errorData.detail || '服务器错误'}</div>`;
                            } else {
                                const textContent = await response.text();
                                console.error('错误响应内容:', textContent.substring(0, 200));
                                responseText.innerHTML = `<div class="alert alert-danger">查询失败: 服务器错误 (${response.status})</div>`;
                            }
                        } catch (e) {
                            responseText.innerHTML = `<div class="alert alert-danger">查询失败: 服务器错误 (${response.status})</div>`;
                        }
                        audioContainer.classList.add('d-none');
                        imageContainer.classList.add('d-none');
                    }
                } catch (err) {
                    // 处理网络错误或其他异常
                    console.error('查询处理出错:', err);
                    responseText.innerHTML = `<div class="alert alert-danger">查询失败: ${err.message || '未知错误'}</div>`;
                    audioContainer.classList.add('d-none');
                    imageContainer.classList.add('d-none');
                }
            });

            // 初始状态 - 检查语音服务是否可用
            async function checkSpeechService() {
                try {
                    const response = await fetch('/system-status');
                    if (response.ok) {
                        const status = await response.json();

                        // 查看语音识别服务状态
                        if (status && status.speech_interaction) {
                            const asr_available = status.speech_interaction.asr_available;
                            // 检查是否有deepseek_asr字段，且值为false
                            if (asr_available && asr_available.deepseek_asr === false) {
                                // 语音识别不可用，禁用相关功能
                                speechToTextUnavailable = true;
                                startButton.classList.add('disabled');
                                startButton.title = '语音识别功能暂时不可用';

                                recordingStatus.innerHTML = `<span class="text-warning">语音识别功能暂时不可用，请使用键盘输入或选择预设问题</span>`;
                                setTimeout(() => {
                                    recordingStatus.textContent = '';
                                }, 5000);
                            }

                            // 检查语音合成服务状态
                            const tts_available = status.speech_interaction.tts_available;
                            if (tts_available) {
                                const ttsServices = Object.values(tts_available);
                                // 如果所有TTS服务都不可用
                                if (ttsServices.every(service => service === false)) {
                                    // 禁用语音回答选项
                                    voiceResponseCheckbox.checked = false;
                                }
                            }
                        }
                    }
                } catch (e) {
                    console.warn('无法检查语音服务状态:', e);
                }
            }

            // 启动时检查语音服务
            checkSpeechService();
        });
    </script>
</body>
</html>